package com.devenv.common.plugin;

import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

/**
 * 文件处理接口
 * <p>
 * 定义了统一的文件处理服务接口，支持文件上传、验证、审核、转换等功能的插件化扩展。
 * 包括头像审核、图片处理、文档转换等功能。
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
public interface IFileHandler {

    /**
     * 获取文件处理器的名称
     * <p>
     * 用于标识不同的文件处理器，如："avatar", "document", "image"等
     * </p>
     * 
     * @return 文件处理器名称，不能为null
     */
    @NonNull
    String getName();

    /**
     * 获取文件处理器的显示名称
     * <p>
     * 用于在UI界面显示给用户，如："头像处理", "文档转换", "图片处理"等
     * </p>
     * 
     * @return 文件处理器显示名称，不能为null
     */
    @NonNull
    String getDisplayName();

    /**
     * 获取支持的文件类型
     * <p>
     * 返回该处理器支持的文件MIME类型列表
     * </p>
     * 
     * @return 支持的文件类型列表，如["image/jpeg", "image/png"]，不能为null
     */
    @NonNull
    List<String> getSupportedMimeTypes();

    /**
     * 获取文件大小限制
     * <p>
     * 返回该处理器支持的最大文件大小（字节）
     * </p>
     * 
     * @return 最大文件大小，-1表示无限制
     */
    long getMaxFileSize();

    /**
     * 检查文件处理器是否可用
     * <p>
     * 用于检查文件处理服务是否正常工作，包括存储空间、外部服务等
     * </p>
     * 
     * @return true表示可用，false表示不可用
     */
    boolean isAvailable();

    /**
     * 验证文件是否有效
     * <p>
     * 对上传的文件进行基础验证，包括文件类型、大小、内容等
     * </p>
     * 
     * @param file 待验证的文件，不能为null
     * @return 验证结果，包含验证状态和错误信息，不能为null
     * @throws FileHandleException 验证过程中出现错误时抛出
     */
    @NonNull
    ValidationResult validateFile(@NonNull MultipartFile file) throws FileHandleException;

    /**
     * 处理文件上传
     * <p>
     * 处理文件上传请求，包括存储、转换、生成缩略图等操作
     * </p>
     * 
     * @param file 上传的文件，不能为null
     * @param config 处理配置，可以为null使用默认配置
     * @return 文件处理结果，包含文件信息、访问URL等，不能为null
     * @throws FileHandleException 处理过程中出现错误时抛出
     */
    @NonNull
    FileProcessResult processFile(@NonNull MultipartFile file, @Nullable ProcessConfig config) throws FileHandleException;

    /**
     * 审核文件内容
     * <p>
     * 对文件内容进行审核，检测违规内容，如色情、暴力、政治敏感等
     * </p>
     * 
     * @param filePath 文件路径，不能为null或空字符串
     * @return 审核结果，包含审核状态和置信度，不能为null
     * @throws FileHandleException 审核过程中出现错误时抛出
     * @since 1.0.0
     */
    @NonNull
    AuditResult auditFile(@NonNull String filePath) throws FileHandleException;

    /**
     * 删除文件
     * <p>
     * 删除指定的文件及其相关资源（缩略图、备份等）
     * </p>
     * 
     * @param filePath 文件路径，不能为null或空字符串
     * @return true表示删除成功，false表示文件不存在或删除失败
     * @throws FileHandleException 删除过程中出现错误时抛出
     * @since 1.0.0
     */
    boolean deleteFile(@NonNull String filePath) throws FileHandleException;

    /**
     * 获取文件信息
     * <p>
     * 获取指定文件的详细信息，包括大小、类型、创建时间等
     * </p>
     * 
     * @param filePath 文件路径，不能为null或空字符串
     * @return 文件信息，文件不存在时返回null
     * @throws FileHandleException 获取信息过程中出现错误时抛出
     * @since 1.0.0
     */
    @Nullable
    FileInfo getFileInfo(@NonNull String filePath) throws FileHandleException;

    /**
     * 文件验证结果
     */
    class ValidationResult {
        private final boolean valid;
        private final String message;
        private final String errorCode;

        public ValidationResult(boolean valid, String message) {
            this.valid = valid;
            this.message = message;
            this.errorCode = valid ? null : "VALIDATION_ERROR";
        }

        public ValidationResult(boolean valid, String message, String errorCode) {
            this.valid = valid;
            this.message = message;
            this.errorCode = errorCode;
        }

        public boolean isValid() { return valid; }
        public String getMessage() { return message; }
        public String getErrorCode() { return errorCode; }
    }

    /**
     * 文件处理结果
     */
    class FileProcessResult {
        private final boolean success;
        private final String filePath;
        private final String fileUrl;
        private final String thumbnailUrl;
        private final long fileSize;
        private final String mimeType;
        private final Map<String, Object> metadata;
        private final String message;

        public FileProcessResult(boolean success, String message) {
            this.success = success;
            this.message = message;
            this.filePath = null;
            this.fileUrl = null;
            this.thumbnailUrl = null;
            this.fileSize = 0;
            this.mimeType = null;
            this.metadata = null;
        }

        public FileProcessResult(boolean success, String filePath, String fileUrl, 
                               String thumbnailUrl, long fileSize, String mimeType, 
                               Map<String, Object> metadata, String message) {
            this.success = success;
            this.filePath = filePath;
            this.fileUrl = fileUrl;
            this.thumbnailUrl = thumbnailUrl;
            this.fileSize = fileSize;
            this.mimeType = mimeType;
            this.metadata = metadata;
            this.message = message;
        }

        // Getters
        public boolean isSuccess() { return success; }
        public String getFilePath() { return filePath; }
        public String getFileUrl() { return fileUrl; }
        public String getThumbnailUrl() { return thumbnailUrl; }
        public long getFileSize() { return fileSize; }
        public String getMimeType() { return mimeType; }
        public Map<String, Object> getMetadata() { return metadata; }
        public String getMessage() { return message; }
    }

    /**
     * 文件审核结果
     */
    class AuditResult {
        private final AuditStatus status;
        private final double confidence;
        private final String reason;
        private final Map<String, Object> details;

        public AuditResult(AuditStatus status, double confidence, String reason) {
            this.status = status;
            this.confidence = confidence;
            this.reason = reason;
            this.details = null;
        }

        public AuditResult(AuditStatus status, double confidence, String reason, Map<String, Object> details) {
            this.status = status;
            this.confidence = confidence;
            this.reason = reason;
            this.details = details;
        }

        // Getters
        public AuditStatus getStatus() { return status; }
        public double getConfidence() { return confidence; }
        public String getReason() { return reason; }
        public Map<String, Object> getDetails() { return details; }

        /**
         * 审核状态枚举
         */
        public enum AuditStatus {
            APPROVED,   // 审核通过
            REJECTED,   // 审核拒绝
            PENDING,    // 待审核
            REVIEWING   // 审核中
        }
    }

    /**
     * 处理配置
     */
    class ProcessConfig {
        private final boolean generateThumbnail;
        private final int thumbnailWidth;
        private final int thumbnailHeight;
        private final boolean enableAudit;
        private final Map<String, Object> customOptions;

        public ProcessConfig(boolean generateThumbnail, int thumbnailWidth, int thumbnailHeight, 
                           boolean enableAudit, Map<String, Object> customOptions) {
            this.generateThumbnail = generateThumbnail;
            this.thumbnailWidth = thumbnailWidth;
            this.thumbnailHeight = thumbnailHeight;
            this.enableAudit = enableAudit;
            this.customOptions = customOptions;
        }

        // Getters
        public boolean isGenerateThumbnail() { return generateThumbnail; }
        public int getThumbnailWidth() { return thumbnailWidth; }
        public int getThumbnailHeight() { return thumbnailHeight; }
        public boolean isEnableAudit() { return enableAudit; }
        public Map<String, Object> getCustomOptions() { return customOptions; }
    }

    /**
     * 文件信息
     */
    class FileInfo {
        private final String fileName;
        private final String filePath;
        private final long fileSize;
        private final String mimeType;
        private final long createTime;
        private final long modifyTime;
        private final Map<String, Object> metadata;

        public FileInfo(String fileName, String filePath, long fileSize, String mimeType, 
                       long createTime, long modifyTime, Map<String, Object> metadata) {
            this.fileName = fileName;
            this.filePath = filePath;
            this.fileSize = fileSize;
            this.mimeType = mimeType;
            this.createTime = createTime;
            this.modifyTime = modifyTime;
            this.metadata = metadata;
        }

        // Getters
        public String getFileName() { return fileName; }
        public String getFilePath() { return filePath; }
        public long getFileSize() { return fileSize; }
        public String getMimeType() { return mimeType; }
        public long getCreateTime() { return createTime; }
        public long getModifyTime() { return modifyTime; }
        public Map<String, Object> getMetadata() { return metadata; }
    }

    /**
     * 文件处理异常类
     */
    class FileHandleException extends Exception {
        
        private final String errorCode;
        
        public FileHandleException(String message) {
            super(message);
            this.errorCode = "FILE_HANDLE_ERROR";
        }
        
        public FileHandleException(String message, Throwable cause) {
            super(message, cause);
            this.errorCode = "FILE_HANDLE_ERROR";
        }
        
        public FileHandleException(String errorCode, String message) {
            super(message);
            this.errorCode = errorCode;
        }
        
        public FileHandleException(String errorCode, String message, Throwable cause) {
            super(message, cause);
            this.errorCode = errorCode;
        }
        
        public String getErrorCode() {
            return errorCode;
        }
    }
}
